package com.rentapark.app;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.google.android.maps.GeoPoint;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import com.google.android.maps.GeoPoint;

import data.DB;
import data.OwnerListAdapter;
import data.Request;

public class OwnerList extends ListActivity{
	DB parking_db;
	List<Request> requestList;
	ProgressDialog progressDialog;
	private final Handler handler = new Handler() {  

		//this method is for handling server's response
		public void handleMessage(Message msg) {
			String result = msg.getData().getString("RESPONSE"); 
			progressDialog.dismiss(); 
			requestList= new ArrayList<Request>();
			ListView list = getListView();
			list.setClickable(true);

			try {

				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				DocumentBuilder db = dbf.newDocumentBuilder();
				Document doc = db.parse(new InputSource(new StringReader(result)));
				NodeList nodeList = doc.getElementsByTagName("Offer");
				String address="";
				if(nodeList!=null && nodeList.getLength()>0)
				{
					//filling a list of offers and each offer's requests
					for(int i = 0 ; i < nodeList.getLength();i++)
					{
						Element el = (Element)nodeList.item(i);
						int spotID=getIntegerValue(el,"spotID");
						Log.d("lists- spot id",Integer.toString(spotID));
						parking_db=DB.getInstance();
						if((parking_db.dbList!=null)&&(parking_db.dbList.list.size()>0))
						{
							for(int j=0;j<parking_db.dbList.list.size();j++)
							{
								
								if(parking_db.dbList.list.get(j).spotId==spotID)
								{
									address=parking_db.dbList.list.get(j).address;	
								}
									
							}
						}
					//if address wasn't found in the local DB, find it according to the geopoint
						if(address.equals(""))
						{
							double latitud=getDoubleValue(el,"latitud");
							double longitud=getDoubleValue(el,"longitud");
							GeoPoint point=new GeoPoint((int)(latitud*1e6),(int)(longitud*1e6));
							address=getReverseGeoCoder(point);
						}
						Log.d("address is: ",address);
						double candID=getDoubleValue(el,"cand_id");
						String phone=getTextValue(el,"candidatePhone");
						String stringName = getTextValue(el,"candidateName");
						int intGrade=getIntegerValue(el,"candidateGrade");
						Log.d("toAdd","one");
						requestList.add(new Request(address,stringName,intGrade,spotID,candID,phone));
					}
				}
				else//the offer has no requests/ the user has made no offers
				{
					Toast toast = Toast.makeText(OwnerList.this, "There's no relevant request for your offers", Toast.LENGTH_SHORT);
					toast.show();
					finish();
				}
				OwnerListAdapter adapter = new OwnerListAdapter(OwnerList.this, requestList);
				list.setOnItemClickListener(new OnItemClickListener() {

					//on clicking an item, the spot's address is shown
					public void onItemClick(AdapterView<?> arg0, View arg1, int position,
							long index) {
						System.out.println("sadsfsf");
						Toast toast = Toast.makeText(OwnerList.this, requestList.get(position).address, Toast.LENGTH_SHORT);
						toast.show();

					}
				});

				list.setAdapter(adapter);
			}
			catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} 
	};
	//onCreate
	public void onCreate(Bundle savedInstanceState){   
		super.onCreate(savedInstanceState);
		//getting DB instance
		parking_db=DB.getInstance();
		//send server a request for information
		performRequest("http://"+parking_db.instanceDNS+":8080/ParkAndLetPark/OwnersRequest");

	}
	//onStart
	public void onStart(){
		super.onStart();
		Log.d("onStart", "ListSubs");

	}
	//this method receives a geopoint and returns the point's address
	protected String getReverseGeoCoder (GeoPoint point){
		Geocoder geoCoder= new Geocoder(getBaseContext(),Locale.getDefault());
		String 	display ="";
		try
		{
			List<Address> address =geoCoder.getFromLocation(point.getLatitudeE6()/1E6, point.getLongitudeE6()/1E6, 1);
			if(address.size()>0)
			{

				for(int i=0;i<address.get(0).getMaxAddressLineIndex();i++)
				{		
					display += address.get(0).getAddressLine(i)+ "\n";
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return display;
	}
	//this method send a request to the server for information about the offer's requests
	private void performRequest(final String uri) { 
		// create HTTP response handler to handle the HTTP response
		// the response data is extracted from the HTTP message and then it is wrapped in a message
		// which  is passed to the android handler for handling
		final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {   
			public String handleResponse(HttpResponse response) {    
				//StatusLine status = response.getStatusLine();        
				HttpEntity entity = response.getEntity();          
				String result = null; 
				try { 
					result = data.CommonUtilities.inputStreamToString(entity.getContent());   
					Message message = new Message();     
					Bundle bundle = new Bundle();         
					bundle.putString("RESPONSE", result); 
					message.setData(bundle); 
					handler.sendMessage(message);         
				} catch (IOException e) { 
					Log.e("Class6",  " ", e); 
				} 
				return result; 
			} 
		}; 


		this.progressDialog = ProgressDialog.show(this, "", "executing");
		// create and run the thread that perform the request and handle the response
		new Thread() {                          
			@Override 
			public void run() { 
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(uri);
				parking_db=DB.getInstance();
				try {
					try{
						DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

						DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();

						//creating a new instance of a DOM to build a DOM tree.
						Document doc = docBuilder.newDocument();
						Element Request = doc.createElement("MSG_TYPE");
						Request.appendChild(doc.createTextNode("OWNER_REQUESTS"));
						doc.appendChild(Request);

						Element Userid=doc.createElement("USER_ID");
						Userid.appendChild(doc.createTextNode(Double.toString(parking_db.userID)));//can be 0 on newUser!!
						Request.appendChild(Userid);


						TransformerFactory factory = TransformerFactory.newInstance();
						Transformer transformer = factory.newTransformer();

						transformer.setOutputProperty(OutputKeys.INDENT, "yes");

						StringWriter sw = new StringWriter();
						StreamResult result = new StreamResult(sw);
						DOMSource source = new DOMSource(doc);
						transformer.transform(source, result);
						String xmlString = sw.toString();
						Log.d("xmlString",xmlString);


						StringEntity se = new StringEntity(xmlString); //XML as a string
						se.setContentType("text/xml"); //declare it as XML
						httppost.setEntity(se);

						String response = httpclient.execute(httppost,responseHandler);
						Log.d("","*server response* "+response);
					}
					catch (ClientProtocolException e) {
						Log.e("LOGTAG", " " , e); 
					} catch (IOException e) {
						Log.e("LOGTAG", " " , e); 
					}

				}
				catch(Exception e)
				{
					Log.e("LOGTAG", " " , e); 
				}
			}

		}.start(); 
	}
	//this method is for finding a specific string value in an xml
	private String getTextValue(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}

		return textVal;
	}


	//this method is for finding a specific double value in an xml
	private double getDoubleValue(Element ele, String tagName) {
		String strVal = null;
		double doubleVal=0;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			strVal = el.getFirstChild().getNodeValue();
			doubleVal=Double.parseDouble(strVal);
		}

		return doubleVal;
	}
	//this method is for finding a specific int value in an xml
	private int getIntegerValue(Element ele, String tagName) {
		String strVal = null;
		int intVal=0;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			strVal = el.getFirstChild().getNodeValue();
			intVal=Integer.parseInt(strVal);
		}

		return intVal;
	}
	//on Restart-> in onRestart the activity is closed automatically if the previous activity closed a deal
	public void onRestart()
	{
		super.onRestart();
		Log.d("notificationHandler","onRestart");
		SharedPreferences ref = getSharedPreferences("com.ruthy.parkApp",MODE_PRIVATE);
		if((ref.getString("notificationHandler", "-1").equals("finish")))
		{
			SharedPreferences.Editor ed = ref.edit();
			ed.putString("notificationHandler", "-1");
			ed.commit();
			finish();
		}
	}


}
